<template>
  <div style="border: 1px solid red;margin: 20px;padding: 20px;">
    <h1>大文件上传</h1>
    <input type="file" @change="handleFileSelect" />
    <p v-if="uploadProgress !== 0">上传进度: {{ uploadProgress }}%</p>
    <p v-if="mergeProgress">正在合并文件...</p>
  </div>
</template>

<script setup>
import { ref } from "vue"

const uploadProgress = ref(0) // 上传进度
const mergeProgress = ref(false) // 合并状态


const handleFileSelect = async (event) => {
  const file = event.target.files[0]
  if (!file) return
  const chunkSize = 5 * 1024 * 1024 // 分片大小 5MB
  const totalChunks = Math.ceil(file.size / chunkSize);
  const fileHash = await calculateFileHash(file); // 计算文件唯一 Hash
  // 1. 请求已上传分片
  const uploadedChunks = await getUploadedChunks(fileHash)
  const uploadedChunksSet = new Set(uploadedChunks)

  for (let i = 0; i < totalChunks; i++) {
    if (uploadedChunksSet.has(i.toString())) {
      // 如果该分片已上传，跳过
      console.log(`分片 ${i} 已经上传了, 跳过...`)
      uploadProgress.value = Math.round(((i + 1) / totalChunks) * 100)
      continue
    }
    const start = i * chunkSize
    const end = Math.min(file.size, start + chunkSize)
    const chunk = file.slice(start, end)
    //发送请求
    const formData = new FormData()
    formData.append("chunk", chunk)
    formData.append("fileName", file.name)
    formData.append("chunkIndex", i)
    formData.append("totalChunks", totalChunks)
    formData.append("fileHash", fileHash)
    try {
      await fetch("http://localhost:3200/upload/chunk", {
        method: "POST",
        body: formData,
      });

      // 更新进度
      uploadProgress.value = Math.round(((i + 1) / totalChunks) * 100)
    } catch (error) {
      console.error(`Chunk ${i} upload failed`, error)
    }
  }

  // 通知后端合并文件
  mergeProgress.value = true;
  try {
    await fetch("http://localhost:3200/upload/merge", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        fileHash,
        fileName: file.name,
      }),
    })
    alert("文件上传完成！");
  } catch (error) {
    console.error("Merge failed:", error)
  } finally {
    mergeProgress.value = false
    uploadProgress.value = 0
  }
}


const getUploadedChunks = async (fileHash) => {
  try {
    const response = await fetch(`http://localhost:3200/upload/status?fileHash=${fileHash}`)
    const data = await response.json()
    return data.uploadedChunks || []
  } catch (error) {
    console.error("Error fetching uploaded chunks:", error)
    return []
  }
}



const calculateFileHash = (file) => {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onload = () => {
      // 简单生成文件 hash
      const hash = btoa(reader.result).slice(0, 16)
      resolve(hash)
    };
    reader.readAsBinaryString(file)
  });
}
</script>
